home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 December / december_2000.iso / Intercd / root / Multimedia / audio / ^NoiseTracker / NtkSourceCode / tb303.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-01  |  8.1 KB  |  305 lines

  1. //
  2. // This is a Public Source Code.[Open Source Project]
  3. //
  4. // Roland TB303 Software Synthesizer Emulation v0.1b:
  5. //
  6. // By Juan Antonio Arguelles Rius - arguru@vermail.net
  7. //
  8. // Please, feel free to make any suggestion, verification,
  9. // correction, to this code, since I dont have the Roland tb303
  10. // nor hardware documentation about this machine.
  11. //
  12. // (C)Tb303 is a trademark from Roland.
  13. //
  14. // Code based on Propellerhead's Rebirth v2
  15. //
  16. struct flag303
  17. {
  18.     unsigned slide_flag:1;
  19.     unsigned accent_flag:1;
  20.     unsigned transposeup_flag:1;
  21.     unsigned transposedown_flag:1;
  22.     unsigned pause:1;
  23.     unsigned reserved2_flag:1;
  24.     unsigned reserved3_flag:1;
  25.     unsigned reserved4_flag:1;
  26. };
  27.  
  28. struct para303{
  29. unsigned char enabled;            //Enabled                  UBYTE           0       0x00 = off, 0x01 = on (pattern mode)
  30. unsigned char selectedpattern;    //Selected pattern        UBYTE           1       0x00 to 0x20 (pattern mode)
  31. unsigned char tune;                //Tune                    UBYTE           2       0x00 to 0x7f (pattern mode)
  32. unsigned char cutoff;            //Cutoff                  UBYTE           3       0x00 to 0x7f (pattern mode)
  33. unsigned char resonance;        //Resonance               UBYTE           4       0x00 to 0x7f (pattern mode)
  34. unsigned char envmod;            //EnvMod                  UBYTE           5       0x00 to 0x7f (pattern mode)
  35. unsigned char decay;            //Decay                   UBYTE           6       0x00 to 0x7f (pattern mode)
  36. unsigned char accent;            //Accent                  UBYTE           7       0x00 to 0x7f (pattern mode)
  37. unsigned char waveform;            //Waveform                UBYTE           8       0x00 = triangle, 0x01 = square (pattern mode)
  38. unsigned char patternlength[32];
  39. unsigned char tone[32][16];
  40. struct flag303 flag[32][16];
  41.  
  42.     //    32*Pattern (1088 bytes)             9,9+(1*34),9+(2*34),9+(3*34)...
  43.     //    |   Shuffle         UBYTE                   0x00 = off, 0x01 = on
  44.     //    |   Pattern length  UBYTE                   0x01 to 0x10
  45.     //    |
  46.     //    |   16*Step (32 bytes)              11,11+(1*34),11+(2*34),11+(3*34)...
  47.     //    |   |   Tone/pitch  UBYTE                   0x00 to 0x0c
  48.     //    |   |   Flags       BITMASK8                bit 0 = No slide/Slide (0x01)
  49.     //    |   |                                       bit 1 = No accent/Accent (0x02)
  50.     //    |   |                                       bit 2 = Normal/Transpose up (0x04)
  51.     //    |   |                                       bit 3 = Normal/Transpose down (0x08)
  52.     //    \   \                                       bit 4 = Pause/Note (0x10)
  53.  
  54. };
  55.  
  56.  
  57. class gear303
  58. {
  59. public:
  60.     unsigned char tbPattern; // From 0 to 31, 255 - Off
  61.     unsigned char tbLine; // From 0 to 15, 255 - Off
  62.     
  63.     gear303();
  64.     void tbNoteOn(int tbNote,para303 *PARAT303);
  65.  
  66.     float tbGetSample(void);
  67.     void tbUpdate(para303 *tbpars);    
  68.     bool hpf;
  69.     float tbBuf0;
  70.     float tbBuf1;
  71.     float tbVolume;
  72.     
  73. private:
  74.  
  75.     float tbFilter(float input,float f,float q);
  76.  
  77.     // 303 Parameters
  78.     float tbTune;
  79.     float tbCutoff;
  80.     float tbResonance;
  81.     float tbEnvmod;
  82.     float tbDecay;
  83.     float tbAccent;
  84.     float tbSample;
  85.     float tbRealCutoff;
  86.     float tbRealVolume;
  87.     float tbOscSpeedFreak;
  88.     float tbTargetVolume;
  89.     float tbCurrentVolume;
  90.     float tbInnertime;
  91.     // Oscillator variables
  92.     float tbOscPosition;
  93.     float tbOscSpeed;
  94.     
  95.     // Filter Input/Output history
  96.     
  97.     // Waveform Type
  98.     char tbWaveform;
  99. };
  100.  
  101.     // Constructor, 303 initialization
  102.  
  103. gear303::gear303()
  104. {
  105.     tbPattern=255;
  106.     tbLine=255;
  107.     tbCurrentVolume=0.5;
  108.     tbVolume=0.5f;
  109.     tbRealVolume=0.5f;
  110.     tbInnertime=0.0f;
  111.     tbTargetVolume=0.5f;
  112.     tbRealCutoff=0.5f;
  113.     tbTune=0.0f;
  114.     tbCutoff=0.5f;
  115.     tbResonance=0.5f;
  116.     tbEnvmod=0.5f;
  117.     tbDecay=0.5f;
  118.     tbAccent=0.5f;
  119.     
  120.     tbBuf0=0.0f;
  121.     tbBuf1=0.0f;
  122.     tbOscSpeedFreak=0.0f;
  123.  
  124.     tbSample=0.0f;
  125.     tbOscPosition=0.0f;
  126.     tbOscSpeed=0.0f;
  127.     hpf=false;
  128.     tbWaveform=0;
  129. }
  130.  
  131.     // Update parameters from a pointer to a 'para303' structure
  132.  
  133. void gear303::tbUpdate(para303 *tbpars)
  134. {
  135.     tbTune=((float)tbpars->tune-64.0f)*0.015625f;
  136.     tbCutoff=(float)tbpars->cutoff*0.0078125f;
  137.     tbResonance=(float)tbpars->resonance*0.0078125f;
  138.     tbEnvmod=(float)tbpars->envmod*0.0078125f;
  139.     tbDecay=(float)tbpars->decay*0.0078125f;
  140.     tbAccent=(float)tbpars->accent*0.0078125f;
  141.     tbWaveform=tbpars->waveform;
  142. }
  143.  
  144.     // Render 1 32bit-float sample
  145.  
  146. float gear303::tbGetSample(void)
  147. {
  148.         // Get Oscillator values
  149.     
  150.     switch(tbWaveform)
  151.     {
  152.     
  153.         // SawTooth
  154.     case 0:
  155.         tbSample=tbOscPosition;
  156.     break;
  157.  
  158.         // Square
  159.     case 1:
  160.         if(tbOscPosition<0)
  161.             tbSample=-16384;
  162.         else
  163.             tbSample=16384;
  164.     break;
  165.     }
  166.  
  167.     if (tbCurrentVolume<tbTargetVolume)
  168.         tbCurrentVolume+=0.0078125f;
  169.     else
  170.         tbCurrentVolume-=0.0078125f;
  171.  
  172.         // Run Oscillator
  173.  
  174.     tbOscPosition+=tbOscSpeed;
  175.     
  176.     if(tbInnertime>0)
  177.     {
  178.         tbInnertime--;
  179.         tbOscSpeed+=tbOscSpeedFreak;
  180.     }
  181.     
  182.     if(tbOscPosition>=16384)tbOscPosition-=32768;
  183.     
  184.     tbRealCutoff=tbCutoff+tbEnvmod;
  185.     tbEnvmod-=tbDecay*tbRealCutoff*0.015625f;
  186.  
  187.     if(tbRealCutoff<tbCutoff)tbRealCutoff=tbCutoff;
  188.     tbSample*=tbCurrentVolume;
  189.     return tbFilter(tbSample,tbRealCutoff,tbResonance);
  190. }
  191.  
  192.     // Do Note On
  193.  
  194. void gear303::tbNoteOn(int tbNote,para303 *PARAT303)
  195. {
  196.     if(PARAT303->flag[tbPattern][tbLine].transposeup_flag)tbNote+=12;
  197.     if(PARAT303->flag[tbPattern][tbLine].transposedown_flag)tbNote-=12;
  198.     tbWaveform=PARAT303->waveform;    
  199.     tbOscSpeedFreak=0;
  200.     float frune=float(tbNote)-17;
  201.     frune+=(float)PARAT303->tune*0.1889763f;
  202.     tbOscSpeed=(float)pow(2.0,frune/12.0f)*64;
  203.     
  204.     if(PARAT303->flag[tbPattern][tbLine].pause)
  205.     {
  206.     tbCutoff=float(PARAT303->cutoff+1)*0.0026041f;
  207.     tbEnvmod=(tbCutoff*2)+(float)PARAT303->envmod*0.0009531f;
  208.     tbResonance=(float)PARAT303->resonance*0.0078125f;
  209.     tbDecay=(128.0f-(float)PARAT303->decay)*0.000122f;
  210.     tbRealVolume=tbVolume;
  211.     }
  212.         
  213.     // Slide check...
  214.     
  215.     // Hay glide? no hay decay...
  216.     if(PARAT303->flag[tbPattern][tbLine].slide_flag)tbDecay=0.0f;
  217.  
  218.     // Aqui se mira el glide de atras...
  219.  
  220.     char tbLine2=tbLine-1;
  221.     if(tbLine<0)tbLine=PARAT303->patternlength[tbPattern]-1;
  222.     bool forcefault=true;
  223.     if(PARAT303->flag[tbPattern][tbLine2].slide_flag)
  224.     {
  225.     forcefault=false;
  226.     frune=float(PARAT303->tone[tbPattern][tbLine2])-17;
  227.     if(PARAT303->flag[tbPattern][tbLine2].transposeup_flag)frune+=12;
  228.     if(PARAT303->flag[tbPattern][tbLine2].transposedown_flag)frune-=12;
  229.     frune+=(float)PARAT303->tune*0.1889763f;
  230.     tbInnertime=SamplesPerTick*0.5f;
  231.     float tbDestiny=tbOscSpeed; // Velocidad Destino
  232.     float tbSource=((float)pow(2.0,frune/12.0f)*64); // Velocidad fuente
  233.     tbOscSpeed=tbSource; // Intercambioce....
  234.     tbOscSpeedFreak=(tbDestiny-tbSource)/tbInnertime; // Calculo del coeficiente del glide
  235.     }
  236.  
  237.     if(PARAT303->flag[tbPattern][tbLine].accent_flag)
  238.     {    
  239.         float accenta=(float)PARAT303->accent*0.0001765f;
  240.         tbResonance+=accenta;
  241.         tbCutoff+=accenta;
  242.         tbRealVolume*=((accenta*64.0f)+1.0f);
  243.     }
  244.  
  245.     if(!PARAT303->flag[tbPattern][tbLine].pause && forcefault)
  246.         tbRealVolume=0;
  247.  
  248.     tbTargetVolume=tbRealVolume;
  249.     
  250. }
  251.  
  252. //
  253. // Filter routine.
  254. //
  255. // This is a 2pole filter [-12db/Octave] Lowpass filter.
  256. // It seems that the original Roland Tb303 has got a 3pole filter.
  257. //
  258.  
  259. float gear303::tbFilter(float input,float f,float q)
  260. {
  261.   input++;
  262.   if(f>0.999f)f=0.999f;
  263.   if(f<0.005f)f=0.005f;
  264.   if(q>0.98f)q=0.98f;
  265.   if(q<0.01f)q=0.01f;
  266.  
  267.   float fa = float(1.0 - f); 
  268.   float fb = float(q * (1.0 + (1.0/fa)));
  269.   tbBuf0 = fa * tbBuf0 + f * (input + fb * (tbBuf0 - tbBuf1)); 
  270.   tbBuf1 = fa * tbBuf1 + f * tbBuf0;
  271.   return (hpf?input-tbBuf1:tbBuf1);
  272. }
  273.  
  274. void RESET303PARAMETERS(para303 *tbpars)
  275. {
  276. tbpars->enabled=0;
  277. tbpars->selectedpattern=0;
  278. tbpars->tune=64;
  279. tbpars->cutoff=64;
  280. tbpars->resonance=64;
  281. tbpars->envmod=64;
  282. tbpars->decay=64;
  283. tbpars->accent=64;
  284. tbpars->waveform=0;
  285.  
  286. for (char c=0;c<32;c++)
  287. {
  288.     tbpars->patternlength[c]=16;
  289.     
  290.     for (char d=0;d<16;d++)
  291.     {
  292.     tbpars->tone[c][d]=0;
  293.     tbpars->flag[c][d].slide_flag=0;
  294.     tbpars->flag[c][d].accent_flag=0;
  295.     tbpars->flag[c][d].transposeup_flag=0;
  296.     tbpars->flag[c][d].transposedown_flag=0;
  297.     tbpars->flag[c][d].pause=1;
  298.     tbpars->flag[c][d].reserved2_flag=0;
  299.     tbpars->flag[c][d].reserved3_flag=0;
  300.     tbpars->flag[c][d].reserved4_flag=0;
  301.     }
  302. }
  303.  
  304. }
  305.